package session

import (
	"AccessAdmin/internal/model"
	"AccessAdmin/internal/model/entity"
	"AccessAdmin/internal/service"
	"context"
)

type sSession struct{}

const (
	sessionKeyUser         = "SessionKeyUser"    // 用户信息存放在Session中的Key
	sessionKeyLoginReferer = "SessionKeyReferer" // Referer存储，当已存在该session时不会更新。用于用户未登录时引导用户登录，并在登录后跳转到登录前页面。
	sessionKeyMenus        = "sessionKeyMenus"   // 存放在Session中的菜单信息
	sessionKeyRoutes       = "sessionKeyRoutes"  // 存放在Session中的路由信息
)

func init() {
	service.RegisterSession(New())
}

func New() *sSession {
	return &sSession{}
}

// SetUser 设置用户Session.
func (s *sSession) SetUser(ctx context.Context, user *entity.UserAdmin) error {
	return service.BizCtx().Get(ctx).Session.Set(sessionKeyUser, user)
}

// GetUser 获取当前登录的用户信息对象，如果用户未登录返回nil。
func (s *sSession) GetUser(ctx context.Context) *entity.UserAdmin {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		v, _ := customCtx.Session.Get(sessionKeyUser)
		if !v.IsNil() {
			var user *entity.UserAdmin
			_ = v.Struct(&user)
			return user
		}
	}
	return &entity.UserAdmin{}
}

// RemoveUser 删除用户Session。
func (s *sSession) RemoveUser(ctx context.Context) error {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		return customCtx.Session.Remove(sessionKeyUser)
	}
	return nil
}

// SetLoginReferer 设置LoginReferer.
func (s *sSession) SetLoginReferer(ctx context.Context, referer string) error {
	if s.GetLoginReferer(ctx) == "" {
		customCtx := service.BizCtx().Get(ctx)
		if customCtx != nil {
			return customCtx.Session.Set(sessionKeyLoginReferer, referer)
		}
	}
	return nil
}

// GetLoginReferer 获取LoginReferer.
func (s *sSession) GetLoginReferer(ctx context.Context) string {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		return customCtx.Session.MustGet(sessionKeyLoginReferer).String()
	}
	return ""
}

// RemoveLoginReferer 删除LoginReferer.
func (s *sSession) RemoveLoginReferer(ctx context.Context) error {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		return customCtx.Session.Remove(sessionKeyLoginReferer)
	}
	return nil
}

// SetMenus 设置菜单信息
func (s *sSession) SetMenus(ctx context.Context, menus []*model.MenuItem) error {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		return customCtx.Session.Set(sessionKeyMenus, menus)
	}
	return nil
}

// GetMenus 获取菜单信息
func (s *sSession) GetMenus(ctx context.Context) ([]*model.MenuItem, error) {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		var menus []*model.MenuItem
		v, err := customCtx.Session.Get(sessionKeyMenus)
		if err != nil {
			return nil, err
		}
		if err = v.Scan(&menus); err != nil {
			return nil, err
		}
		return menus, nil
	}
	return nil, nil
}

// RemoveMenus 删除菜单信息
func (s *sSession) RemoveMenus(ctx context.Context) error {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		return customCtx.Session.Remove(sessionKeyMenus)
	}
	return nil
}

// SetRoutes 设置路由信息
func (s *sSession) SetRoutes(ctx context.Context, menus []*model.MenuData) error {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		return customCtx.Session.Set(sessionKeyRoutes, menus)
	}
	return nil
}

// GetRoutes 获取路由信息
func (s *sSession) GetRoutes(ctx context.Context) ([]*model.MenuData, error) {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		var routes []*model.MenuData
		v, err := customCtx.Session.Get(sessionKeyRoutes)
		if err != nil {
			return nil, err
		}
		if err = v.Scan(&routes); err != nil {
			return nil, err
		}
		return routes, nil
	}
	return nil, nil
}

// RemoveRoutes 删除路由信息
func (s *sSession) RemoveRoutes(ctx context.Context) error {
	customCtx := service.BizCtx().Get(ctx)
	if customCtx != nil {
		return customCtx.Session.Remove(sessionKeyRoutes)
	}
	return nil
}
